package dao

import (
	"errors"
	"fmt"
	"time"
	"yundian/internel/app/helper"
	"yundian/internel/app/helper/request"
	"yundian/internel/app/models/goods"
	"yundian/internel/app/models/membermodel"
	"yundian/internel/app/models/placemodel"
	"yundian/internel/pkg/dbs"
	"yundian/internel/pkg/dingo"
	"yundian/internel/pkg/dingo/global"
	"yundian/internel/pkg/utils"
)

type GoodsDao struct {
}

func NewGoodsDao() *GoodsDao {
	return &GoodsDao{}
}

func (d *GoodsDao) HandleStewardStatisticsShop(param *request.StewardStatisticsReq) *dingo.ErrorWrap {
	var lst []*request.StewardStatisticsShopRes
	db := global.Orm.Table("goods_orders go").Select("go.goods_id,g.name,COUNT(1)num")
	db.Joins("LEFT JOIN goods g ON go.goods_id = g.id").Where("go.status IN ?", []int{2, 3, 4})

	//if param.IsAdmin != helper.TypeNumIsAdminOperator {
	//	db.Where("go.user_id=?", param.LoginUserId)
	//}

	if !helper.IsAdminAndStaff(param.IsAdmin, param.ParentId) {
		db.Where("go.user_id = ?", param.LoginUserId)
	}

	if param.PlaceId > 0 {
		db.Where("go.place_id=?", param.PlaceId)
	}
	if param.StartTime != "" {
		db.Where("go.create_time>=?", param.StartTime)
	}
	if param.EndTime != "" {
		db.Where("go.create_time<=?", param.EndTime)
	}

	db.Group("go.goods_id").Order("num DESC").Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

// 查询可提现商品订单
func (dao *GoodsDao) GetGoodsOrdersToCashByUserId(param *request.OrdersCashReq) *dingo.ErrorWrap {
	dbData := &request.OrdersCashRes{}

	t, _ := time.ParseDuration("-48h")
	minTime := "'" + time.Now().Add(t).Format("2006-01-02 15:04:05") + "'"
	fields := fmt.Sprintf(`SUM(IF(pay_time<=%s,amount,0))cash,SUM(IF(pay_time>%s,amount,0))not_cash`, minTime, minTime)
	db := global.Orm.Table("goods_orders").Select(fields)
	db.Where("status=? AND third_trade_no<>'' AND user_id=?", helper.TypeNumGoodsOrderStatusShipped, param.UserId)

	db.Find(&dbData)
	return dingo.ErrorIf(db.Error, dbData)
}

// 根据状态查询商品订单
func (dao *GoodsDao) GetGoodsOrdersByStatus(status uint8) (lst []*goods.Orders, err error) {
	t, _ := time.ParseDuration("-5m")
	minTime := time.Now().Add(t).Format("2006-01-02 15:04:05")
	db := global.Orm.Table("goods_orders").Where("status=? AND pay_type<>1", status)
	db.Where("create_time<=?", minTime)
	db.Order("goods_id").Limit(1000).Find(&lst)
	return lst, db.Error
}

// GetGoodsOrdersByNotificationIds 更新支付金额
func (dao *GoodsDao) GetGoodsOrdersByNotificationIds(notificationIds []int) *dingo.ErrorWrap {
	var lst []*request.GoodsListOrderRes
	fields := `notification_id,COUNT(1) goods_num, SUM(amount) all_amount, trade_no, status`
	db := global.Orm.Table("goods_orders").Select(fields).Where("notification_id in ?", notificationIds)
	db.Group("trade_no").Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

// 更新支付金额
func (dao *GoodsDao) UpdateGoodsOrdersAmount(tradeNo string, amount int) error {
	updateData := map[string]interface{}{"amount": amount}
	db := global.Orm.Table("goods_orders").Where("trade_no=?", tradeNo).Updates(updateData)
	return db.Error
}

// 设置商品状
func (dao *GoodsDao) SetAdminGoodsOrdersStatus(goodsOrderInfo *goods.Orders, param *request.SetGoodsOrderStatusReq) *dingo.ErrorWrap {
	//goodsOrderInfo := dao.GetAdminGoodsOrdersInfo(param).Unwrap().(*goods.Orders)
	if goodsOrderInfo.Id <= 0 {
		return dingo.ErrorIf(nil, goodsOrderInfo)
	}

	db := global.Orm.Table("goods_orders").Where("trade_no=?", param.TradeNo)

	//if param.IsAdmin != helper.TypeNumIsAdminOperator {
	//	db.Where("user_id=?", param.LoginUserId)
	//}
	if !helper.IsAdminAndStaff(param.IsAdmin, param.ParentId) {
		db.Where("user_id=?", param.LoginUserId)
	}
	db.Update("status", param.Status)

	notificationUpdate := map[string]interface{}{
		"status": helper.TypeNumNotificationStatusFinish,
	}
	if param.RejectMessage != "" {
		notificationUpdate["service_message"] = param.RejectMessage
	}
	global.Orm.Table("places_service_notification").Where("id=? AND status<>?", goodsOrderInfo.NotificationId,
		helper.TypeNumNotificationStatusFinish).Updates(notificationUpdate)

	return dingo.ErrorIf(db.Error, goodsOrderInfo)
}

func (dao *GoodsDao) GetH5GoodsOrdersInfo(param *request.StewardSetDataReq) *dingo.ErrorWrap {
	goodsOrderInfo := &goods.Orders{}

	db := global.Orm.Table("goods_orders go").Select("go.*,SUM(amount)amount")
	db.Joins("LEFT JOIN places_staff ps ON go.place_id=ps.place_id")
	db.Where("trade_no=?", param.GoodsTradeNo).Where("ps.staff_id=?", param.LoginUserId)

	db.Find(&goodsOrderInfo)
	return dingo.ErrorIf(db.Error, goodsOrderInfo)
}

func (dao *GoodsDao) GetAdminGoodsOrdersInfo(param *request.SetGoodsOrderStatusReq) *dingo.ErrorWrap {
	goodsOrderInfo := &goods.Orders{}

	db := global.Orm.Table("goods_orders go").Select("go.*,SUM(amount)amount")
	db.Where("trade_no=?", param.TradeNo)

	//if param.IsAdmin != helper.TypeNumIsAdminOperator {
	//	db.Where("user_id=?", param.LoginUserId)
	//}
	if !helper.IsAdminAndStaff(param.IsAdmin, param.ParentId) {
		db.Where("user_id=?", param.LoginUserId)
	}

	db.Find(&goodsOrderInfo)
	return dingo.ErrorIf(db.Error, goodsOrderInfo)
}

func (dao *GoodsDao) GetAdminGoodsOrdersDetailsReq(param *request.GoodsOrderDetailsReq) *dingo.ErrorWrap {
	var goodsOrderList []*request.GetStewardGoodsOrderListRes

	fields := `go.id,go.goods_id,go.price,go.amount,go.buy_num,go.notification_id,g.name,g.icon,go.place_name,go.status,go.message,
	go.address room,DATE_FORMAT(go.create_time,'%Y-%m-%d %T')create_time,DATE_FORMAT(go.pay_time,'%Y-%m-%d %T')pay_time`
	db := global.Orm.Table("goods_orders go").Select(fields)
	db.Joins("LEFT JOIN goods g ON go.goods_id=g.id")
	db.Where("trade_no=?", param.TradeNo)

	if helper.IsAdminAndStaff(param.IsAdmin, param.ParentId) {
		db.Where("user_id=?", param.LoginUserId)
	}

	db.Order("id DESC").Find(&goodsOrderList)

	dataInfo := &request.GetStewardGoodsOrderDetailsRes{GoodsOrderList: goodsOrderList}
	if len(goodsOrderList) > 0 {
		dataInfo.TradeNo = param.TradeNo
		dataInfo.Status = goodsOrderList[0].Status
		dataInfo.NotificationId = goodsOrderList[0].NotificationId
		dataInfo.Room = goodsOrderList[0].Room
		dataInfo.PlaceName = goodsOrderList[0].PlaceName
		dataInfo.PayTime = goodsOrderList[0].PayTime
		dataInfo.CreateTime = goodsOrderList[0].CreateTime
		dataInfo.Message = goodsOrderList[0].Message
	}
	if db.Error != nil || len(goodsOrderList) == 0 || goodsOrderList[0].NotificationId == 0 {
		return dingo.ErrorIf(db.Error, dataInfo)
	}

	notificationData := NewNotificationDaoDao().GetNotificationServiceInfoById(goodsOrderList[0].NotificationId).
		Unwrap().(*placemodel.PlacesServiceNotification)
	dataInfo.StaffId = notificationData.UserId
	dataInfo.NotificationStatus = notificationData.Status

	return dingo.ErrorIf(db.Error, dataInfo)
}

// EmptyGoodsBuyCart 购物车-清空
func (dao *GoodsDao) EmptyGoodsBuyCart(param *request.SetGoodsBuyCartReq) *dingo.ErrorWrap {
	db := global.Orm.Table("goods_buy_cart").Where("member_id=? AND place_id=?", param.MemberId, param.PlaceId).Delete("")
	return dingo.ErrorIf(db.Error)
}

// DeleteGoodsBuyCart 购物车-删除
func (dao *GoodsDao) DeleteGoodsBuyCart(param *request.SetGoodsBuyCartReq) *dingo.ErrorWrap {
	db := global.Orm.Table("goods_buy_cart").Where("member_id=? AND goods_id=?", param.MemberId, param.GoodsId).Delete("")
	return dingo.ErrorIf(db.Error)
}

// SetGoodsBuyCart 购物车-新增/更新
func (dao *GoodsDao) SetGoodsBuyCart(param *request.SetGoodsBuyCartReq) *dingo.ErrorWrap {
	if param.BuyNum <= 0 {
		return dao.DeleteGoodsBuyCart(param)
	}

	sql := fmt.Sprintf(`INSERT INTO goods_buy_cart (member_id,buy_num, place_id, goods_id, price)
	(SELECT %d member_id,%d buy_num,place_id,id,price FROM goods WHERE id=?) ON DUPLICATE KEY UPDATE 
	place_id=VALUES(place_id),buy_num=VALUES(buy_num),price=VALUES(price)`, param.MemberId, param.BuyNum)
	db := global.Orm.Exec(sql, param.GoodsId)

	return dingo.ErrorIf(db.Error)
}

// GetWxGoodsBuyCartList 购物车-查询列表
func (dao *GoodsDao) GetWxGoodsBuyCartList(param *request.GetStewardGoodsBuyCartReq) *dingo.ErrorWrap {
	var lst []*request.GetStewardGoodsBuyCartRes

	fields := `gbc.id,gbc.member_id,gbc.place_id,gbc.goods_id,gbc.buy_num,gbc.price,
	g.icon,g.name,g.num,g.price t_price,g.status,g.discount_amount`
	db := global.Orm.Table("goods_buy_cart gbc").Select(fields)
	db.Joins("LEFT JOIN goods g on gbc.goods_id = g.id")
	db.Where("gbc.member_id=? AND gbc.place_id=? AND g.place_id=?", param.MemberId, param.PlaceId, param.PlaceId)

	db.Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

// 查询订单详情
func (dao *GoodsDao) GetH5GoodsOrdersDetailsReq(param *request.GetH5StewardGoodsOrderDetailsReq) *dingo.ErrorWrap {
	var goodsOrderList []*request.GetStewardGoodsOrderListRes

	fields := `go.id,go.goods_id,go.price,go.amount,go.buy_num,go.notification_id,g.name,g.icon,go.place_name,go.status,go.message,
	go.address room,DATE_FORMAT(go.create_time,'%Y-%m-%d %T')create_time,DATE_FORMAT(go.pay_time,'%Y-%m-%d %T')pay_time,go.trade_no`
	db := global.Orm.Table("goods_orders go").Select(fields)
	db.Joins("LEFT JOIN goods g ON go.goods_id=g.id")
	db.Where("go.notification_id=?", param.NotificationId)
	db.Order("id DESC").Find(&goodsOrderList)

	dataInfo := &request.GetStewardGoodsOrderDetailsRes{GoodsOrderList: goodsOrderList}
	if len(goodsOrderList) > 0 {
		dataInfo.TradeNo = goodsOrderList[0].TradeNo
		dataInfo.Status = goodsOrderList[0].Status
		dataInfo.NotificationId = goodsOrderList[0].NotificationId
		dataInfo.Room = goodsOrderList[0].Room
		dataInfo.PlaceName = goodsOrderList[0].PlaceName
		dataInfo.PayTime = goodsOrderList[0].PayTime
		dataInfo.CreateTime = goodsOrderList[0].CreateTime
		dataInfo.Message = goodsOrderList[0].Message
	}
	if db.Error != nil || len(goodsOrderList) == 0 || goodsOrderList[0].NotificationId == 0 {
		return dingo.ErrorIf(db.Error, dataInfo)
	}

	notificationData := NewNotificationDaoDao().GetNotificationServiceInfoById(goodsOrderList[0].NotificationId).
		Unwrap().(*placemodel.PlacesServiceNotification)
	dataInfo.StaffId = notificationData.UserId
	dataInfo.NotificationStatus = notificationData.Status

	return dingo.ErrorIf(db.Error, dataInfo)
}

// 查询订单详情
func (dao *GoodsDao) GetWxGoodsOrdersDetailsReq(param *request.GetStewardGoodsOrderDetailsReq) *dingo.ErrorWrap {
	var goodsOrderList []*request.GetStewardGoodsOrderListRes

	fields := `go.id,go.goods_id,go.price,go.amount,go.buy_num,go.notification_id,g.name,g.icon,go.place_name,go.status,go.message,
	go.address room,DATE_FORMAT(go.create_time,'%Y-%m-%d %T')create_time,DATE_FORMAT(go.pay_time,'%Y-%m-%d %T')pay_time`
	db := global.Orm.Table("goods_orders go").Select(fields)
	db.Joins("LEFT JOIN goods g ON go.goods_id=g.id")
	db.Where("member_id=? AND trade_no=?", param.MemberId, param.TradeNo)
	db.Order("id DESC").Find(&goodsOrderList)

	dataInfo := &request.GetStewardGoodsOrderDetailsRes{GoodsOrderList: goodsOrderList}
	if len(goodsOrderList) > 0 {
		dataInfo.TradeNo = param.TradeNo
		dataInfo.Status = goodsOrderList[0].Status
		dataInfo.NotificationId = goodsOrderList[0].NotificationId
		dataInfo.Room = goodsOrderList[0].Room
		dataInfo.PlaceName = goodsOrderList[0].PlaceName
		dataInfo.PayTime = goodsOrderList[0].PayTime
		dataInfo.CreateTime = goodsOrderList[0].CreateTime
		dataInfo.Message = goodsOrderList[0].Message
	}
	if db.Error != nil || len(goodsOrderList) == 0 || goodsOrderList[0].NotificationId == 0 {
		return dingo.ErrorIf(db.Error, dataInfo)
	}

	notificationData := NewNotificationDaoDao().GetNotificationServiceInfoById(goodsOrderList[0].NotificationId).
		Unwrap().(*placemodel.PlacesServiceNotification)
	dataInfo.StaffId = notificationData.UserId
	dataInfo.NotificationStatus = notificationData.Status

	return dingo.ErrorIf(db.Error, dataInfo)
}

// GetWxGoodsOrders 查询商品订单
func (dao *GoodsDao) GetWxGoodsOrders(param *request.GetStewardGoodsOrderReq) *dingo.ErrorWrap {
	var (
		lst    []*request.GetStewardGoodsOrderRes
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)

	fields := `id,member_id,place_id,goods_id,place_name,place_address,address,address_id,status,pay_type,SUM(amount)amount,message,
	third_trade_no,trade_no,COUNT(1)buy_num, price,DATE_FORMAT(pay_time,'%Y-%m-%d %T')pay_time,DATE_FORMAT(logistics_time,'%Y-%m-%d %T')
	logistics_time,DATE_FORMAT(create_time,'%Y-%m-%d %T')create_time,DATE_FORMAT(update_time,'%Y-%m-%d %T')update_time`
	db := global.Orm.Table("goods_orders").Select(fields)
	db.Where("member_id=?", param.MemberId)

	if param.Status > 0 {
		db.Where("status=?", param.Status)
	}

	db.Group("trade_no").Order("trade_no DESC")
	db.Limit(limit).Offset(offset).Find(&lst)

	where := ``
	if param.Status > 0 {
		where = fmt.Sprintf(" AND status = %d ", param.Status)
	}
	countSql := fmt.Sprintf(`SELECT COUNT(1) FROM (SELECT trade_no FROM goods_orders WHERE member_id=? %s GROUP BY trade_no) go`, where)
	global.Orm.Raw(countSql, param.MemberId).Find(&count)
	return dingo.ErrorIf(db.Error, lst, count)
}

// 校验商品
func (dao *GoodsDao) CheckGoodsNum(params *request.CreateStewardOrderReq) (goodsInvalidList []*goods.Goods, err error) {
	var goodsIds []int
	var goodsList []*goods.Goods
	goodsMap := map[int]int{}
	for _, item := range params.GoodsList {
		goodsMap[item.Id] = item.Num
		goodsIds = append(goodsIds, item.Id)
	}
	db := global.Orm.Model(&goods.Goods{})
	if db.Where("place_id=? AND id IN ?", params.PlaceId, goodsIds).Find(&goodsList); db.Error != nil {
		return goodsInvalidList, db.Error
	}

	if len(params.GoodsList) != len(goodsList) {
		return goodsInvalidList, errors.New("参数错误")
	}

	for _, item := range goodsList {
		if item.Num < goodsMap[item.Id] {
			goodsInvalidList = append(goodsInvalidList, item)
		}
	}
	return goodsInvalidList, nil
}

// CancelGoodsOrder 取消商品订单
func (dao *GoodsDao) CancelGoodsOrder(params *request.CreateStewardOrderReq) error {
	orderData := dao.GetGoodsOrdersListByTradeNo(params.TradeNo, helper.TypeNumGoodsOrderStatusWait)
	goodsOrderList := orderData.Unwrap().([]*goods.OrderUpdate)
	if len(goodsOrderList) == 0 {
		return errors.New("无效订单")
	}
	for _, item := range goodsOrderList {
		params.GoodsList = append(params.GoodsList, request.GoodsList{Id: item.GoodsId, Num: -item.BuyNum})
	}
	if err := dao.UpdateGoodsNum(params); err != nil {
		return err
	}

	return nil
}

// 更新商品数量
func (dao *GoodsDao) UpdateGoodsNum(params *request.CreateStewardOrderReq) error {
	if len(params.GoodsList) == 0 {
		return nil
	}

	updateSql := "UPDATE goods SET num=num-?,sell_num=sell_num+? WHERE id=?"
	tx, key := dbs.GormBegin("CalAgentBonus")
	for _, item := range params.GoodsList {
		if db := tx.Exec(updateSql, item.Num, item.Num, item.Id); db.Error != nil {
			dbs.GormRollback(tx, key, db.Error)
			return db.Error
		}
	}

	status := helper.TypeNumGoodsOrderStatusCancel
	if params.GoodsList[0].Num > 0 {
		status = helper.TypeNumGoodsOrderStatusDonePay
	}
	if db := tx.Table("goods_orders").Where("trade_no", params.TradeNo).Update("status", status); db.Error != nil {
		dbs.GormRollback(tx, key, db.Error)
		return db.Error
	}

	dbs.GormCommit(tx, key)
	return nil
}

// 根据订单标识 查询商品
func (dao *GoodsDao) GetGoodsOrdersListByTradeNo(tradeNo string, status uint8) *dingo.ErrorWrap {
	var goodsOrderList []*goods.OrderUpdate
	db := global.Orm.Model(&goods.OrderUpdate{}).Where("trade_no=?", tradeNo)

	if status > 0 {
		db.Where("status=?", status)
	}

	db.Find(&goodsOrderList)
	return dingo.ErrorIf(db.Error, goodsOrderList)
}

// UpdateGoodsOrders 更新商品订单
func (dao *GoodsDao) UpdateGoodsOrders(params *goods.OrderUpdate) error {
	updateData := map[string]interface{}{"status": params.Status}

	if params.Status == helper.TypeNumGoodsOrderStatusDonePay {
		updateData["pay_time"] = time.Now().Format("2006-01-02 15:04:05")
	} else if params.Status == helper.TypeNumGoodsOrderStatusShipped {
		updateData["logistics_time"] = time.Now().Format("2006-01-02 15:04:05")
	}

	if params.NotificationId > 0 {
		updateData["notification_id"] = params.NotificationId
	}

	if params.ThirdTradeNo != "" {
		updateData["third_trade_no"] = params.ThirdTradeNo
	}

	db := global.Orm.Model(&params).Where("trade_no=?", params.TradeNo)

	if params.MemberId > 0 {
		db.Where("member_id=?", params.MemberId)
	}
	db.Updates(updateData)

	return db.Error
}

// InsertGoodsOrders 批量写入商品订单
func (dao *GoodsDao) InsertGoodsOrders(insertList []*goods.OrderUpdate) ([]*goods.OrderUpdate, error) {
	db := global.Orm.Create(insertList)
	return insertList, db.Error
}

// GetGoodsByIds 根据商品ID查询商品列表
func (dao *GoodsDao) GetGoodsByIds(goodIds []int) (lst []*goods.Goods) {
	global.Orm.Table("goods").Where("id in ?", goodIds).Find(&lst)
	return lst
}

// GetWxGoodsTypeList 商品类型列表
func (dao *GoodsDao) GetWxGoodsTypeList(param *request.GetStewardGoodsReq) *dingo.ErrorWrap {
	var lst []*request.GetStewardGoodsOrderTypeRes

	db := global.Orm.Table("goods").Select(`place_id,type_name`)
	db.Where("status= 2 AND num>0 AND place_id=?", param.PlaceId)

	db.Group("type_name").Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

func (dao *GoodsDao) GetDrawGoodsPrizeList() *dingo.ErrorWrap {
	var lst []*request.GetDrawGoodsPrizeListRes

	fields := `CONCAT(LEFT(m.phone,3),'***',RIGHT(m.phone,3))phone,g.name`
	db := global.Orm.Table("third_comment tc").Select(fields)
	db.Joins("LEFT JOIN goods g ON tc.goods_id=g.id")
	db.Joins("LEFT JOIN members m ON m.id=tc.member_id")
	db.Where("g.buy_type=2")
	db.Group("tc.member_id,tc.goods_id")
	db.Order("tc.id DESC")

	db.Limit(100).Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

// GetWxGoodsList 商品列表
func (dao *GoodsDao) GetWxGoodsList(param *request.GetStewardGoodsReq) *dingo.ErrorWrap {
	var (
		lst    []*goods.Goods
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)

	fields := `id,place_id,status,type,price,discount_amount,coupon_id,num,sell_num,icon,img_list,brand_name,name,
	type_name,message,probability,DATE_FORMAT(create_time,'%Y-%m-%d %T')create_time,DATE_FORMAT(update_time,'%Y-%m-%d %T')update_time`
	db := global.Orm.Table("goods").Select(fields)
	db.Where("status= 2 AND num>0 AND place_id=?", param.PlaceId)

	if param.BuyType > 0 {
		db.Where("buy_type = ?", param.BuyType)
	}
	if param.TypeName != "" {
		db.Where("type_name = ?", param.TypeName)
	}

	db.Order("create_time DESC")
	db.Limit(limit).Offset(offset).Find(&lst).Limit(-1).Offset(-1).Count(&count)
	return dingo.ErrorIf(db.Error, lst, count)
}

//商品列表
func (dao *GoodsDao) GetGoodsList(param *request.GoodsListReq) *dingo.ErrorWrap {
	var (
		lst    []*goods.Goods
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)

	db := global.Orm.Table("goods")
	db.Where("status= 2 AND place_id=0")

	if param.Name != "" {
		db.Where("name like ?", fmt.Sprint("%", param.Name, "%"))
	}

	if param.Type > 0 {
		db.Where("type= ?", param.Type)
	}

	if param.BuyType > 0 {
		db.Where("buy_type = ?", param.BuyType)
	}

	db.Order("create_time DESC")
	db.Limit(limit).Offset(offset).Find(&lst).Limit(-1).Offset(-1).Count(&count)
	return dingo.ErrorIf(db.Error, lst, count)
}

//查询商品详情
func (dao *GoodsDao) GetGoodsDetails(param *request.GoodsListReq) *dingo.ErrorWrap {
	dataNumInfo := &goods.Goods{}

	fields := `id, place_id,status, type, price, discount_amount, coupon_id, icon, img_list,
	num,brand_name,name,message,DATE_FORMAT(create_time,'%Y-%m-%d %T')create_time`
	db := global.Orm.Table("goods ").Select(fields)
	db.Where("id = ?", param.Id)
	db.Where("status = 2")

	db.Find(&dataNumInfo)
	return dingo.ErrorIf(db.Error, dataNumInfo)
}

func (dao *GoodsDao) GetAdminGoodsOrderList(param *request.GoodsOrderListReq) *dingo.ErrorWrap {
	var (
		lst []*request.GoodsListOrderRes
		//count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)

	fields := `device_sn,go.user_id,notification_id,trade_no,third_trade_no,go.id,member_id,SUM(amount)all_amount,
	place_id,goods_id,p.place_name,place_address,go.address,address_id,go.status,pay_type,message,COUNT(1)GoodsNum, 
	DATE_FORMAT(pay_time,'%Y-%m-%d %T')pay_time,DATE_FORMAT(logistics_time,'%Y-%m-%d %T')logistics_time, 
	DATE_FORMAT(create_time,'%Y-%m-%d %T')create_time,DATE_FORMAT(update_time,'%Y-%m-%d %T')update_time`
	db := global.Orm.Table("goods_orders go").Select(fields)
	db.Joins("LEFT JOIN places p ON go.place_id=p.id")
	db.Where("go.place_id>0")

	if helper.IsAdminAndStaff(param.IsAdmin, param.ParentId) {
		db.Where("p.user_id=?", param.LoginUserId)
	}

	if param.MemberPhone != "" {
		db.Joins("LEFT JOIN members m ON m.id=go.member_id")
		db.Where("m.phone= ?", param.MemberPhone)
	}
	if param.Room != "" {
		db.Where("go.address= ?", param.Room)
	}
	if param.TradeNo != "" {
		db.Where("go.trade_no= ?", param.TradeNo)
	}
	if param.PlaceId > 0 {
		db.Where("go.place_id= ?", param.PlaceId)
	}
	if param.UserId > 0 {
		db.Where("go.user_id= ?", param.UserId)
	}
	if param.Status > 0 {
		db.Where("go.status= ?", param.Status)
	}
	if param.PayType > 0 {
		db.Where("go.pay_type= ?", param.PayType)
	}

	db.Group("trade_no").Order("trade_no DESC")
	db.Limit(limit).Offset(offset).Find(&lst)
	return dingo.ErrorIf(db.Error, lst, dao.GetAdminGoodsOrderListCount(param))
}

func (dao *GoodsDao) GetAdminGoodsOrderListCount(param *request.GoodsOrderListReq) (count int64) {
	sql := `SELECT COUNT(1) FROM (SELECT * FROM goods_orders %s GROUP BY trade_no) go`
	whereSql := "WHERE"

	if helper.IsAdminAndStaff(param.IsAdmin, param.ParentId) {
		whereSql += fmt.Sprintf(" user_id=%d", param.LoginUserId)
	}

	if param.PlaceId > 0 {
		whereSql += fmt.Sprintf(" %s place_id=%d", utils.AddStrJudge(whereSql == "WHERE", "AND"), param.PlaceId)
	}
	if param.UserId > 0 {
		whereSql += fmt.Sprintf(" %s user_id=%d", utils.AddStrJudge(whereSql == "WHERE", "AND"), param.UserId)
	}
	if param.Status > 0 {
		whereSql += fmt.Sprintf(" %s status=%d", utils.AddStrJudge(whereSql == "WHERE", "AND"), param.Status)
	}
	if param.PayType > 0 {
		whereSql += fmt.Sprintf(" %s pay_type=%d", utils.AddStrJudge(whereSql == "WHERE", "AND"), param.PayType)
	}

	global.Orm.Raw(fmt.Sprintf(sql, utils.AddStrJudge(whereSql == "WHERE", whereSql))).Count(&count)
	return count
}

func (dao *GoodsDao) GetAdminGoodsList(param *request.GoodsListReq, isAdmin uint8) *dingo.ErrorWrap {
	var (
		lst    []*request.GoodsListRes
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)

	fields := `g.id,g.place_id,g.status,g.type,price,discount_amount,coupon_id,num,sell_num,icon,
	img_list,brand_name,name,g.buy_type,g.probability,type_name,message,p.place_name,DATE_FORMAT
	(create_time,'%Y-%m-%d %T')create_time,DATE_FORMAT(update_time,'%Y-%m-%d %T')update_time`
	db := global.Orm.Table("goods g").Select(fields)
	db.Joins("LEFT JOIN places p ON g.place_id=p.id")

	if !helper.IsAdminAndStaff(isAdmin, param.ParentId) {
		//db.Where("p.user_id=?", param.UserId)
		uList := NewUserDao().QueryChildUserIds(param.UserId).Unwrap().([]int)
		pList := NewUserDao().GetPlacesIds(param.UserId, uList).Unwrap().([]int)
		db.Where("p.id IN ?", pList)
	}
	db.Where("g.status<4")

	if param.Name != "" {
		db.Where("g.name like ?", fmt.Sprint("%", param.Name, "%"))
	}
	if param.PlaceId > 0 {
		db.Where("g.place_id=?", param.PlaceId)
	}
	if param.Type > 0 {
		db.Where("g.type= ?", param.Type)
	}

	if param.Status > 0 {
		db.Where("g.status= ?", param.Status)
	}

	db.Order("id DESC")
	db.Limit(limit).Offset(offset).Find(&lst).Limit(-1).Offset(-1).Count(&count)
	return dingo.ErrorIf(db.Error, lst, count)
}

func (dao *GoodsDao) GetAdminInsertGoods(param *goods.UpdateDb) *dingo.ErrorWrap {
	db := global.Orm.Model(&param).Create(&param)
	return dingo.ErrorIf(db.Error, param)
}

func (dao *GoodsDao) GetAdminUpdateGoods(param *goods.UpdateDb) *dingo.ErrorWrap {
	update := map[string]interface{}{
		"place_id":        param.PlaceId,
		"status":          param.Status,
		"type":            param.Type,
		"buy_type":        param.BuyType,
		"probability":     param.Probability,
		"price":           param.Price,
		"discount_amount": param.DiscountAmount,
		"coupon_id":       param.CouponId,
		"num":             param.Num,
		"sell_num":        param.SellNum,
		"icon":            param.Icon,
		"img_list":        param.ImgList,
		"brand_name":      param.BrandName,
		"name":            param.Name,
		"type_name":       param.TypeName,
		"message":         param.Message,
	}
	db := global.Orm.Model(&param).Where("id=?", param.Id).Updates(update)
	return dingo.ErrorIf(db.Error, param)
}

func (dao *GoodsDao) GetAdminGoodsSetStatus(param *goods.UpdateDb) *dingo.ErrorWrap {
	db := global.Orm.Model(&param).Where("id=?", param.Id).Update("status", param.Status)
	return dingo.ErrorIf(db.Error, param)
}

func (dao *GoodsDao) GetAdminGoodsDetails(param *request.GoodsListReq) *dingo.ErrorWrap {
	dataNumInfo := &goods.Goods{}

	fields := `id, place_id,status, type, price, discount_amount, coupon_id, icon, img_list,
	brand_name,name,message,DATE_FORMAT(create_time,'%Y-%m-%d %T')create_time`
	db := global.Orm.Table("goods ").Select(fields)
	db.Where("id = ?", param.Id)

	db.Find(&dataNumInfo)
	return dingo.ErrorIf(db.Error, dataNumInfo)
}

func (dao *GoodsDao) GetGoodsDetailsByNotificationId(notificationId int) *dingo.ErrorWrap {
	dataInfo := &request.GoodsDetailsRes{}

	db := global.Orm.Table("goods g").Select("g.*,go.member_id")
	db.Joins("LEFT JOIN goods_orders go ON g.id=go.goods_id")
	db.Joins("LEFT JOIN third_comment tc ON tc.goods_order_id=go.id")
	db.Where("tc.notification_id = ?", notificationId)

	db.Find(&dataInfo)
	return dingo.ErrorIf(db.Error, dataInfo)
}

//生成商品订单
func (dao *GoodsDao) CreateGoodsOrder(param *request.ThirdCommentSubmitReq) *dingo.ErrorWrap {
	placesModel := &placemodel.PlaceModel{}
	addressModel := &membermodel.MemberAddress{}
	goodsModel := &goods.Goods{}

	//查询网点地址
	fields := `address`
	global.Orm.Table("places").Select(fields).Where("id = ?", param.PlaceId).Find(&placesModel)

	global.Orm.Table("member_address").Where("id = ? and  member_id = ?", param.AddressId, param.MemberId).Find(&addressModel)

	global.Orm.Table("goods").Where("id = ?", param.GoodsId).Find(&goodsModel)

	ordersModel := &goods.OrderUpdate{}
	ordersModel.NotificationId = param.NotificationId
	ordersModel.UserId = placesModel.UserID
	ordersModel.Price = goodsModel.Price
	ordersModel.TradeNo = param.TradeNo
	ordersModel.MemberId = param.MemberId
	ordersModel.PlaceId = param.PlaceId
	ordersModel.GoodsId = param.GoodsId
	ordersModel.PlaceName = param.PlaceName
	ordersModel.PlaceAddress = placesModel.Province + placesModel.City + placesModel.Country + placesModel.Address
	ordersModel.AddressId = param.AddressId
	ordersModel.Address = addressModel.ProvinceName + addressModel.CityName + addressModel.CountyName + addressModel.Address

	ordersModel.Status = 1

	if goodsModel.Type > 2 {
		ordersModel.PayType = 1
	} else {
		ordersModel.PayType = 2
	}
	ordersModel.Amount = goodsModel.Price

	db := global.Orm.Table("goods_orders").Create(&ordersModel)
	return dingo.ErrorIf(db.Error, ordersModel)
}

// GetGoodsListByNotificationIds 根据通知ID查询商品
func (dao *GoodsDao) GetGoodsListByNotificationIds(notificationIds []int) *dingo.ErrorWrap {
	var list []*request.NotificationListRes

	fields := `g.id goods_id, g.name goods_name, tc.notification_id id, tc.id comment_id`
	db := global.Orm.Table("goods g").Select(fields)
	db.Joins("LEFT JOIN third_comment tc ON g.id = tc.goods_id")
	db.Where("tc.notification_id IN ?", notificationIds)

	db.Find(&list)
	return dingo.ErrorIf(db.Error, list)
}
